package com.rp.common.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.security.MessageDigest;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;

/**
 * 平台统一工具类
 * @author HuangJian
 *
 */
public class RpUtil {
	
	/**
	 * 定义了getCurrentTime方法返回的事件格式为：HHmmss
	 */
	public static final String TIME_FORMAT_1 = "HHmmss";
	
	/**
	 * 定义了getCurrentTime方法返回的事件格式为：HH:mm:ss
	 */
	public static final String TIME_FORMAT_2 = "HH:mm:ss";
	
	/**
	 * 获取当前年份
	 * @return
	 */
	public static String getCurrentYear(){
		Calendar calendar = Calendar.getInstance();
		Integer year = calendar.get(Calendar.YEAR);
		return year.toString();
	}
	
	/**
	 * 获取当前月
	 * @return
	 */
	public static String getCurrentMonth(){
		Calendar calendar = Calendar.getInstance();
		Integer month = calendar.get(Calendar.MONTH)+1;
		return month.toString();
	}
	
	/**
	 * 获取当前日
	 * @return
	 */
	public static String getCurrentDay(){
		Calendar calendar = Calendar.getInstance();
		Integer day = calendar.get(Calendar.DATE);
		return day.toString();
	}
	
	/**
	 * 获取当前日期时间，返回的格式为：yyyy-MM-dd HH:mm:ss
	 * @return
	 * @throws Exception
	 */
	public static String getCurrentDatetime(){
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return df.format(new Date());
	}

	/**
	 * 获取当天日期，默认格式为：yyyyMMdd
	 * @param dateFormat 日期的格式，如果传入空字符或NULL，则使用默认格式
	 * @return
	 */
	public static String getTodayDate(String dateFormat){
		Date dt = new Date();
		SimpleDateFormat matter = null;
		if(dateFormat == "" || dateFormat == null){
			matter = new SimpleDateFormat("yyyyMMdd");
		}else{
			matter = new SimpleDateFormat(dateFormat);
		}
		return matter.format(dt);
	}
	
	/**
	 * 获取当前时间
	 * @param format 时间格式：直接通过传入RpUtil的静态变量TIME_FORMAT_1或TIME_FORMAT_2即可
	 * @return
	 * @throws Exception 
	 */
	public static String getCurrentTime(String format) throws Exception{
		int hour, minute, second;
		Calendar cal = Calendar.getInstance();
		hour=cal.get(Calendar.HOUR_OF_DAY);
		minute=cal.get(Calendar.MINUTE);
		second=cal.get(Calendar.SECOND);
		if(format.equals(TIME_FORMAT_1)){
			return ""+hour+minute+second;
		}else if(format.equals(TIME_FORMAT_2)){
			return ""+hour+":"+minute+":"+second;
		}
		throw new Exception("传入的时间格式不正确，请传入RpUtil的静态变量TIME_FORMAT_1或TIME_FORMAT_2");
	}
	
	/**
	 * 获取当前时间的时间戳
	 * @return
	 * @throws ParseException
	 */
	public static long getCurrentDatetimeToTimestamp() {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	    Date date = null;
		try {
			date = df.parse(df.format(new Date()));
		} catch (ParseException e) {
			e.printStackTrace();
		}
	    long timeStemp = date.getTime();
	    return timeStemp;
	}
	
	/**
	 * 解析字符串日期
	 * @param dateStr 日期字符串，例如：2014-09-12 17:23:00
	 * @param format 如果传入的是null，则使用默认的格式化：yyyy-MM-dd HH:mm:ss
	 * @return 返回Date类型日期
	 */
	public static Date parseDate(String dateStr, String format) {
		SimpleDateFormat sdf = null;
		if(format == null){
			sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		}else{
			sdf = new SimpleDateFormat(format);
		}
		try {
			return sdf.parse(dateStr);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * 解析字符串日期
	 * @param dateStr 日期字符串，例如：2014-09-12 17:23:00
	 * @param format 如果传入的是null，则使用默认的格式化：yyyy-MM-dd HH:mm:ss
	 * @return 返回String类型日期
	 */
	public static String parseDate2Str(String dateStr, String format){
		Date date = RpUtil.parseDate(dateStr, format);
		SimpleDateFormat sdf = null;
		if(format == null){
			sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		}else{
			sdf = new SimpleDateFormat(format);
		}
		return sdf.format(date);
	}
	
	
	/**
	 * 生成一个GUID字符串
	 * @return
	 */
	public static String createGuid(){
		UUID uuid = UUID.randomUUID();
		return uuid.toString().toUpperCase();
	}
	
	/**
	 * 生成一个UUID字符串
	 * @return
	 */
	public static String createUuid(){
		return UUID.randomUUID().toString();
	}
	
	/**
	 * 截取出文件的后缀名
	 * @param fileName 带后缀的完整文件名
	 * @return 返回文件后缀名，带有.符号
	 */
	public static String cutFileSuffixName(String fileName) {
		int pos = fileName.lastIndexOf(".");
		return fileName.substring(pos);
	}
	
	
	/**
	 * 转换文件大小，单位为兆（MB），结果保留两位小数
	 * @param initialSize 文件大小初始值，单位为字节，数据类型为long
	 * @return
	 */
	public static Double convertFileSize(long initialSize){
		DecimalFormat df=new DecimalFormat(".##");
		Double size = Double.parseDouble(initialSize+"")/1024/1024;
		return Double.parseDouble(df.format(size));
	}
	
	/**
	 * 删除单个文件
	 * @param filePath 文件的绝对路径
	 * @return 是否删除成功
	 */
	public static boolean deleteFile(String filePath){
		boolean flag = false;  
	    File file = new File(filePath);  
	    // 路径为文件且不为空则进行删除  
	    if (file.isFile() && file.exists()) {  
	        file.delete();  
	        flag = true;  
	    }  
	    return flag;
	}
	
	
	
	/**
	 * MD5加密
	 * @param s 待加密的字符串 
	 * @return
	 */
	public final static String md5Encrypt(String s) {
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'A', 'B', 'C', 'D', 'E', 'F' };

		try {
			byte[] btInput = s.getBytes();
			// 获得MD5摘要算法的 MessageDigest 对象
			MessageDigest mdInst = MessageDigest.getInstance("MD5");
			// 使用指定的字节更新摘要
			mdInst.update(btInput);
			// 获得密文
			byte[] md = mdInst.digest();
			// 把密文转换成十六进制的字符串形式
			int j = md.length;
			char str[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				str[k++] = hexDigits[byte0 >>> 4 & 0xf];
				str[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(str);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 判断一个对象是否为空或空字符
	 * @param obj
	 * @return
	 */
	public static boolean isNullOrEmpty(Object obj) {
		return obj == null || "".equals(obj.toString());
	}
	
	/**
	 * 获取ApplicationContext，读取的配置文件路径为WEB-INF目录下的applicationContext.xml配置文件
	 * @param beanName
	 * @return
	 */
	public static Object getBean(String beanName){
		ApplicationContext ac = new ClassPathXmlApplicationContext("../applicationContext.xml");
		return ac.getBean(beanName);
	}
	
	/**
	 * 测试数据源连接是否正常
	 * @param dbType
	 * @param url
	 * @param username
	 * @param password
	 * @return
	 */
	public static boolean testDsLink(String dbType, String url, String username, String password){
		
		DriverManagerDataSource ds = getDriverManagerDataSource(dbType,url,username,password);

		try {
			ds.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		
		return true;
	}
	
	/**
	 * 获取DriverManagerDataSource数据源
	 * @param dbType
	 * @param url
	 * @param username
	 * @param password
	 * @return
	 */
	public static DriverManagerDataSource getDriverManagerDataSource(
			String dbType, String url, String username, String password){
		DriverManagerDataSource ds = new DriverManagerDataSource();
		ds.setDriverClassName(createDsDriverStr(dbType));
		ds.setUrl(url);
		ds.setUsername(username);
		ds.setPassword(password);
		return ds;
	}
	
	/**
	 * 根据传入的dbType生成数据库驱动类全路径字符串
	 * @param dbType
	 * @return
	 */
	private static String createDsDriverStr(String dbType){
		if(dbType.equals(DbType.ORACLE)){
			return "oracle.jdbc.driver.OracleDriver";
		} else if(dbType.equals(DbType.MSSQL)){
			return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
		} else if(dbType.equals(DbType.MYSQL)){
			return "com.mysql.jdbc.Driver";
		}
		return null;
	}
	
	/**
	 * 读取文件内容
	 * @param path 文件的绝对路径
	 * @return 返回读取的文件内容
	 * @throws IOException
	 */
	public static String readFileContent(String path) throws IOException {
		File file = new File(path);
        if(!file.exists() || file.isDirectory())
            throw new FileNotFoundException();
        //BufferedReader br = new BufferedReader(new FileReader(file));
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path),"UTF-8"));
        String temp = null;
        StringBuffer sb = new StringBuffer();
        temp = br.readLine();
        while(temp != null){
            sb.append(temp + "\r");
            temp = br.readLine();
        }
        br.close();
        return sb.toString();
	}
	
	/**
	 * 写入内容至文件中
	 * @param path 目标文件的绝对路径
	 * @param content 写入的内容
	 * @param append 写入方式是否为append
	 * @return 返回新的文件内容
	 * @throws IOException 
	 */
	public static String writeContent2File(String path, String content, boolean append) throws IOException{
		File file = new File(path);
		if(!file.exists()){
			file.createNewFile();
		}
		
		//FileWriter fileWriter = new FileWriter(file, append);//true代表追加
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, append), "UTF-8"));
		
		if(append){
			writer.write("\n");//加入换行符
		}
		writer.write(content);
		writer.close();
		
		return RpUtil.readFileContent(path);
	}
	
	
	/**
	 * JFinal的分页数据中的List(Recorc)转List(Map)
	 * @param jfinalPage
	 * @return
	 */
	public static List<Map<String, Object>> jfinalPageToList(Page<Record> jfinalPage){
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for (Record r : jfinalPage.getList()) {
			list.add(r.getColumns());
		}
		return list;
	}
	
	/**
	 * JFinal的List(Record)转List(Map)
	 * @param jfinalList
	 * @return
	 */
	public static List<Map<String, Object>> jfinalListToList(List<Record> jfinalList){
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for (Record r : jfinalList) {
			list.add(r.getColumns());
		}
		return list;
	}
	
	/**
	 * 自定义的HTML编码，主要替换一些可用于脚本攻击的特殊字符，例如：尖括号、&、"、等等
	 * @param source
	 * @return
	 */
	public static String htmlEncode(String source){
		if (source == null) {
            return "";
        }
        String html = "";
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < source.length(); i++) {
            char c = source.charAt(i);
            switch (c) {
            case '<':
                buffer.append("&lt;");
                break;
            case '>':
                buffer.append("&gt;");
                break;
            case '&':
                buffer.append("&amp;");
                break;
            case '"':
                buffer.append("&quot;");
                break;
            case '\'':
            	buffer.append("&#x27;");
            	break;
            case '/':
            	buffer.append("&#x2f;");
            	break;
            case 10:
            case 13:
                break;
            default:
                buffer.append(c);
            }
        }
        html = buffer.toString();
        return html;
	}
	
	/*public static String join(Collection<?> s, String delimiter) {
		StringBuffer buffer = new StringBuffer();
		Iterator<?> iter = s.iterator();
		while (iter.hasNext()) {
			buffer.append(iter.next());
			if (iter.hasNext()) {
				buffer.append(delimiter);
			}
		}
		return buffer.toString();
	}*/
	
	public static void main(String[] args) throws Exception {
		//System.out.println(RpUtil.writeContent2File("F:/icons.css", ".icon-import2{background:url(icons/application_osx_down.png) no-repeat;}", false));
		//String content = RpUtil.readFileContent("D:\\tomcat\\apache-tomcat-6.0.37\\webapps\\RaptorPlatform2\\rp\\scripts\\miniui\\themes\\icons.css");
		//System.out.println(content);
		//System.out.println(ESAPI.encoder().encodeForHTML("<script>alert('你好啊');</script>"));
		//System.out.println(RpUtil.htmlEncode("PermGen space异常"));
		
	    //System.out.println(RpUtil.parseDate2Str("2014-12-3 22:34:32", "yyyy-MM-dd HH:mm"));
	    //System.out.println(5*60*1000);
		
		RpUtil.writeContent2File("F:/test.txt", "hello", false);
	}
	
}
